//===============================================================================
// Microsoft patterns & practices
// SharePoint Guidance version 2.0
//===============================================================================
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================
using System.Diagnostics;
using System.Reflection;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Security;

namespace Microsoft.Practices.SPG.Common.Logging
{
    /// <summary>
    /// Loging implementation that writes the log messages to the EventLog.
    /// </summary>
    [SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]
    [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)] 
    public class EventLogLogger : BaseLogger, IEventLogLogger
    {
        /// <summary>
        /// Overrides the Log method to write messages to the eventlog. 
        /// </summary>
        /// <param name="message">Message to write</param>
        /// <param name="eventId">
        /// The eventId that corresponds to the event. This value, coupled with the EventSource is often used by
        /// administrators and IT PRo's to monitor the eventlog of a system. 
        /// </param>
        /// <param name="category">The category to write the message to.</param>
        /// <param name="severity">The severity of the exception.</param>
        [SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)] 
        public override void Log(string message, int eventId, TraceSeverity severity, string category)
        {
            SPSecurity.RunWithElevatedPrivileges( delegate
                                                      {
                                                          WriteEventLogEntry(message, severity, eventId);
                                                      });
        }

        private void WriteEventLogEntry(string message, TraceSeverity severity, int eventId)
        {

            if (!EventLog.SourceExists(this.EventSourceName))
            {
                EventLog.CreateEventSource(this.EventSourceName, "Application");
            }

            EventLog.WriteEntry(this.EventSourceName, message, GetEntryType(severity), eventId);
        }

        /// <summary>
        /// Map the <see cref="TraceSeverity"/> levels from sharepoint to EventLog severity level types. 
        /// </summary>
        /// <param name="severity"></param>
        /// <returns></returns>
        protected virtual EventLogEntryType GetEntryType(TraceSeverity severity)
        {
            switch(severity)
            {
                
                case TraceSeverity.Medium:
                    return EventLogEntryType.Warning;
                case TraceSeverity.Monitorable:
                case TraceSeverity.None:
                case TraceSeverity.Unexpected:
                case TraceSeverity.Verbose:
                    return EventLogEntryType.Information;

                case TraceSeverity.High:
                default:
                    return EventLogEntryType.Error;

            }
        }

        /// <summary>
        /// Get the name of the event source to log messages to. 
        /// </summary>
        protected virtual string EventSourceName
        {
            get
            {
                // We are using the Office Sharepoint Server eventsource name. This means we don't need to create 
                // a custom eventsource (which requires admin priviledges)
                return "Office Sharepoint Server";
            }
        }
    }
}